﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace Virtix
{
    public class BehindHeadCamera
    {
        private Matrix view;
        private Matrix projection;
        private Vector3 lookAt;
        private Vector3 position;
        private Vector3 targetPosition;
        private Vector3 targetDirection;
        private Vector3 lookAtOffset = new Vector3(0, 2.8f, 0);
        private Vector3 desiredPositionOffset = new Vector3(0, 1.5f, 1.0f);
        private float aspectRatio = 4.0f / 3.0f;
        private float fieldOfView = MathHelper.ToRadians(45.0f);
        private float nearPlaneDistance = 1.0f;
        private float farPlaneDistance = 100000.0f;


        #region Properties

        public Vector3 TargetPosition
        {
            get { return targetPosition; }
            set { targetPosition = value; }
        }

        public Vector3 TargetDirection
        {
            get { return targetDirection; }
            set { targetDirection = value; }
        }

        public Vector3 DesiredPositionOffset
        {
            get { return desiredPositionOffset; }
            set { desiredPositionOffset = value; }
        }

        public Vector3 LookAtOffset
        {
            get { return lookAtOffset; }
            set { lookAtOffset = value; }
        }

        public Vector3 LookAt
        {
            get { return lookAt; }
            set { lookAt = value; }
        }

        public Vector3 Position
        {
            get { return position; }
            set { position = value; }
        }

        public float AspectRatio
        {
            get { return aspectRatio; }
            set { aspectRatio = value; }
        }

        public float FieldOfView
        {
            get { return fieldOfView; }
            set { fieldOfView = value; }
        }


        public float NearPlaneDistance
        {
            get { return nearPlaneDistance; }
            set { nearPlaneDistance = value; }
        }

        public float FarPlaneDistance
        {
            get { return farPlaneDistance; }
            set { farPlaneDistance = value; }
        }

        public Matrix View
        {
            get { return view; }
        }

        public Matrix Projection
        {
            get { return projection; }
        }

        #endregion

        /// <summary>
        /// Update position of camera on world
        /// </summary>
        public void Update()
        {
            Matrix transform = Matrix.Identity;
            transform.Forward = TargetDirection;
            transform.Up = Vector3.Up;
            transform.Right = Vector3.Cross(Vector3.Up, TargetDirection);
            lookAt = TargetPosition + Vector3.TransformNormal(LookAtOffset, transform);
            position = TargetPosition + Vector3.TransformNormal(DesiredPositionOffset, transform);
            view = Matrix.CreateLookAt(position, this.LookAt, Vector3.Up);
            projection = Matrix.CreatePerspectiveFieldOfView(FieldOfView, AspectRatio, NearPlaneDistance, FarPlaneDistance);
        }
    }

}
